#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
{
  // 界面初始化
  this->InterfaceInitialization();

  // 对象初始化
  this->ObjectInitialization();

  // 按钮信号连接
  this->ButtonSignalConnect();

  // 线程信号连接
  this->ThreadSignalConnections();
}

void Widget::InterfaceInitialization()
{
  // 界面初始化
  ui = new Ui::Widget;
  ui->setupUi(this);

}

void Widget::ObjectInitialization()
{
  // 创建线程池
  pool = new QThreadPool;
  process = new Process;
  inject = new InjectDLL;
  eject = new EjectDLL;
}

void Widget::InfoUpdate(const QString &message)
{
  ui->TextInfo->append(message);
}

void Widget::ProcessesUpdate(const QList<QPair<QString, DWORD>> &processes)
{
  for (const auto &it : processes)
  {
    ui->Processes->addItem(it.first, QVariant::fromValue<quintptr>((quintptr)it.second));
  }
}

void Widget::RenameDllWithQt(const QString &originalDllPath, const QString &renamedDllPath)
{
  // 提示用户正在进行操作
  ui->TextInfo->append("[+] 正在重命名DLL");
  // 检查原始 DLL 是否存在
  if (!QFile::exists(originalDllPath))
  {
    ui->TextInfo->append("[-] 原始 DLL 文件不存在");
    return;
  }

  // 删除目标路径中已存在的文件（如有必要）
  if (QFile::exists(renamedDllPath))
  {
    if (!QFile::remove(renamedDllPath))
    {
      ui->TextInfo->append("[-] 无法删除已有的目标文件");
      return;
    }
  }

  // 复制原始 DLL 到目标路径
  if (QFile::copy(originalDllPath, renamedDllPath))
  {
    ui->TextInfo->append("[+] DLL 重命名成功:" + renamedDllPath);
  }
  else
  {
    ui->TextInfo->append("[-] DLL 重命名失败");
  }
}



void Widget::DllPathUpdate()
{
  dir = QDir::currentPath();
  // 查找所有 .dll 文件
  filters << "*.dll";
  dllFiles = dir.entryInfoList(filters, QDir::Files | QDir::NoSymLinks);
  for (const auto &fileInfo : dllFiles)
  {
    ui->DllPath->addItem(fileInfo.fileName());
    ui->TextInfo->append(fileInfo.absoluteFilePath());
  }
}

void Widget::ButtonSignalConnect()
{
  connect(ui->ProcessesButton, &QPushButton::clicked, this, [=]()
          {
            ui->Processes->clear();
            pool->start(process);
            process->setAutoDelete(false); });
  connect(ui->DLLButton, &QPushButton::clicked, this, [=]()
          { 
            ui->DllPath->clear();
            this->DllPathUpdate(); });
  connect(ui->Processes, &QComboBox::currentTextChanged, this, [=]()
          { ui->TextInfo->append("PID: " + QString::number(ui->Processes->itemData(ui->Processes->currentIndex()).toInt())); });
  connect(ui->Inject_DLL, &QPushButton::clicked, this, [=]()
          {
            inject->Inject_init((DWORD)ui->Processes->itemData(ui->Processes->currentIndex()).toUInt(), QDir(QDir::currentPath()).filePath(ui->DllPath->currentText()));
            pool->start(inject);
            inject->setAutoDelete(false); });
  connect(ui->Eject_DLL, &QPushButton::clicked, this, [=]()
          {
            eject->Eject_init((DWORD)ui->Processes->itemData(ui->Processes->currentIndex()).toUInt(),ui->DllPath->currentText());
            pool->start(eject);
            eject->setAutoDelete(false); });
}

void Widget::ThreadSignalConnections()
{
  connect(process, &Process::SendProcesses, this, [=](const QList<QPair<QString, DWORD>> &processes)
          { this->ProcessesUpdate(processes); });

  connect(process, &Process::SendDra, this, [=](const QString &message)
          { this->InfoUpdate(message); });

  connect(inject, &InjectDLL::SendDra, this, [=](const QString &message)
          { this->InfoUpdate(message); });

  connect(eject, &EjectDLL::SendDra, this, [=](const QString &message)
          { this->InfoUpdate(message); });
}

Widget::~Widget()
{
  delete ui;
}
